<?php

use think\Log;

class FdsSdk {
	//应用ID
	public static $appId;
	//DSA私钥文件路径
	public static $DSAPrivateKeyFilePath;
	//DSA私钥密碼
	public static $DSAPrivateKeyFilePassword;
	//DSA公钥文件路径
	public static $DSAPublicKeyFilePath;
	//RSA私钥文件路径
	public static $RSAPrivateKeyFilePath;
	//RSA私钥密碼
	public static $RSAPrivateKeyFilePassword;
	//RSA公钥文件路径
	public static $RSAPublicKeyFilePath;
	//网关
	public static $gatewayUrl = "http://123.151.202.122:8080/fds/service/soa";
	//api版本
	public static $apiVersion = "2.0";
	// 表单提交字符集编码
	public static $postCharset = "UTF-8";
	// 文件字符集编码
	private static $fileCharset = "UTF-8";
	//签名类型
	public static $signType = "DSA";
	
	const STATUS_OK   = 'OK';
	const ERR_MESSAGE = 'message';
	const SIGNED_VALUE= 'result';
	
	private $bizContent;
	private $apiMethodName;
	static $bop;
	
	public static function getCashier() {
		if (empty(self::$bop)) {
			self::$bop = new FdsSdk();
		}
		return self::$bop;
	}
	
	public static function getService() {
		if (empty(self::$bop)) {
			self::$bop = new FdsSdk();
		}
		return self::$bop;
	}

    //退款
    public function refund($data)
    {
        $param["order_no"] = $data['order_no'];
        $param["out_request_no"] = $data['out_request_no'];
        $param["refund_amount"] = $data['refund_amount'];//退款总额,退款金额＜=原订单未退款金额
        $param["pay_seq_no"] = $data['pay_seq_no'];//支付流水号
        if (isset($data['refund_rule']))$param['refund_rule'] = $data['refund_rule'];//退款规则

        $this->bizContent = json_encode($param);

        $this->apiMethodName = 'order.consume.refund';
        $result = $this->execute();

        return $result;
    }

    //完成订单（确权分账）
    public function orderComplete($data)
    {
        $param["member_no"] = $data['member_no'];//会员标识
        $param["order_no"] = $data['order_no'];
        $param["out_request_no"] = $data['out_request_no'];//退款总额,退款金额＜=原订单未退款金额
        $param["split_amount"] = $data['split_amount'];//本次要分账的金额，不是支付的金额。
        $param['split_rule_data'] = $data['split_rule_data'];

        $this->bizContent = json_encode($param);

        $this->apiMethodName = 'order.complete';
        $result = $this->execute();
        return $result;
    }

    //查询订单状态
    public function getOrderStatus($data)
    {
        $param["order_no"] = $data['order_no'];//订单编号
        $param["out_order_no"] = $data['out_order_no'];//支付流水号
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'order.status.get';
        $result = $this->execute();
        return $result;
    }

    //查询余额
    public function getBalance($member_no)
    {
        $param["member_no"] = $member_no;//订单编号
        $param["account_type"] = 1000;//支付流水号
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'account.balance.get';
        $result = $this->execute();
        return $result;
    }

    //查询收入金额支出
    public function getBalancePage($member_no,$start_time,$end_time)
    {
        $param["member_no"] = $member_no;//订单编号
        $param["account_type"] = 1000;//支付流水号
        $param["start_time"] = $start_time;
        $param["end_time"] = $end_time;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'account.income.cost.get';
        $result = $this->execute();
        return $result;
    }

    //消费
    public function orderConsume($data)
    {
        //$param['buyer_member_no'] = $data['buyer_member_no'];
        $param["seller_member_no"] = $data['seller_member_no'];//卖家会员标识
        //$param["seller_member_no"] = '6806043394058620928';//卖家会员标识
        $param["out_order_no"] = $data['out_order_no'];//应用平台订单号
        $param["amount"] = $data['amount'];//订单金额
        $param["pay_amount"] = $data['amount'];//
        $param["terminal_ip"] = $data['terminal_ip'];//支付方式为SCAN时，上传支付者IP,其他支付方式，上传商户支付相关设备的ip
        $param["order_name"] = $data['order_name'];//订单名称
        $param["split_mode"] = $data['split_mode'];//0：即时分账 1：确权分账
        $param["pay_method"] = $data['pay_method'];
        $param['back_url'] = $data['back_url'];
        $param['split_rule_data'] = $data['split_rule_data'];

        $this->bizContent = json_encode($param);

        $this->apiMethodName = 'order.consume.request';
        $result = $this->execute();
        return $result;
    }

    //提现
    public function withdraw($data)
    {
        $param["member_no"] = $data['member_no'];//会员标识
        $param["out_order_no"] = $data['out_order_no'];//应用平台订单号
        $param["account_type"] = 1000;
        $param["amount"] = $data['amount']*100;//提现金额（含平台手续费）
        $param["billing_fee"] = $data['billing_fee'];//平台手续费
        $param["bank_card_no"] = $data['bank_card_no'];//钱账通绑定银行卡的编号
        $param["back_url"] = $data['back_url'];//后台通知地址

        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'order.withdraw.request';
        $result = $this->execute();
        return $result;
    }

    public function bindShop($member_no,$channel_merchant_no,$channel_terminal_no,$back_url)
    {
        $param["member_no"] = $member_no;//
        $param["channel_merchant_no"] = $channel_merchant_no;//
        $param["channel_terminal_no"] = $channel_terminal_no;
        $param['merchant_type'] = 'BMCP';
        $param['back_url'] = $back_url;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.merchant.bind';
        $result = $this->execute();
        return $result;
    }

    //会员商户增终
    public function addTerminal($member_no,$mer_no,$back_url)
    {
        $param = [
            'member_no'=>$member_no,
            'mer_no'=>$mer_no,
            'pos_type'=>'B2B_CASHIER_DESK',
            'term_num'=>1,
            'back_url'=>$back_url
        ];
        $fee_rate = [
            'wechat'=>0.38,
            'alipay'=>0.38,
            'debit'=>0.6,
            'debit_pct'=>20,
            'credit'=>0.6,
            'b2b_transfer'=>'0.6',
            'b2b_transfer_pct'=>'20',
            'union_scan_debit'=>'0.6',
            'union_scan_debit_pct'=>'20',
            'union_scan_credit'=>'0.6',
            'union_pay_debit_disc'=>'',
            'union_pay_credit_disc'=>'',
            'union_scan_debit_disc'=>'',
            'union_scan_credit_disc'=>'',
        ];
        $param['fee_rate'] = $fee_rate;
        $this->bizContent = json_encode($param,320);
        Log::error('会员商户增终参数:'.$this->bizContent);
        $this->apiMethodName = 'member.merchant.channel.add.terminal';
        $result = $this->execute();
        return $result;
    }

    //渠道子商户查询
    public function getMerchant($param)
    {

        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.other.channel.sub.merchant.get';
        $result = $this->execute();
        return $result;
    }

    //商户解绑
    public function merchantUnbind($param)
    {

        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.merchant.unbind';
        $result = $this->execute();
        return $result;
    }

	//查询会员信息
    public function memberInfo($out_member_no)
    {
        $param["out_member_no"] = $out_member_no;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.info.query';
        $result = $this->execute();
        return $result;
    }

    //查询会员商户
    public function memberMerchantInfo($out_member_no)
    {
        $param["out_member_no"] = $out_member_no;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.merchant.query';
        $result = $this->execute();

        return $result;
    }

    //查询分账比例
    public function memberSplitScale($member_no)
    {
        $param["member_no"] = $member_no;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.split.scale.query';
        $result = $this->execute();
        return $result;
    }

    //绑卡
    public function memberBindbankCard($data)
    {
        $this->bizContent = json_encode($data);
        $this->apiMethodName = 'member.bank.card.page.url.get';
        $result = $this->execute();
        return $result;
    }



    //会员信息变更
    public function editMember($data)
    {
        //dump($this->jiami($data['legal_identity_no']));die;
        //$data["business_license"] = $this->jiami($data['business_license']);
        //$data["legal_identity_no"] = $this->rsaEncrypt($data['legal_identity_no']);
        $val = $this->rsaEncrypt($data['legal_identity_no']);

        $this->bizContent = json_encode($data,320);
        $this->apiMethodName = 'member.info.change';
        $result = $this->execute();
        return $result;
    }

    //银行卡列表
    public function cardList($member_no)
    {
        $param["member_no"] = $member_no;
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.bank.card.bind.query';
        $result = $this->execute();
        return $result;
    }

    //分账撤销
    public function splitRevoke($order_no,$split_seq_no,$amount)
    {
        $param["order_no"] = $order_no;
        $param["split_seq_no"] = $split_seq_no;
        $param["amount"] = intval($amount*100);

        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'order.split.revoke';
        $result = $this->execute();
        return $result;
    }

    //普通会员开户
    /*public function newCreateMember($data)
    {
        $param["out_member_no"] = $data['out_member_no'];

        $param["out_merchant_no"] =  $data['out_merchant_no'];

        $param["open_part"] = 1;
        $param["member_type"] = 2;
        $param["member_category"] = 0;
        $param["member_role"] = 'R001';
        $param["back_url"] = $data['back_url'];

        $this->bizContent = json_encode($param,320);

        $this->apiMethodName = 'member.open.part.page.url.get';
        $result = $this->execute();

        return $result;
    }*/

    // 开户
    public function createMember($data)
    {

        $param["out_member_no"] = $data['out_member_no'];
        //$param["out_member_no"] = '2_01234567';
        $param["out_merchant_no"] =  $data['out_merchant_no'];
        //$param["out_merchant_no"] = $data['shop_id'].'_'.\fast\Random::numeric(8);
        $param["open_part"] = 2;//1：普通会员 2：收单商户
        $param["back_url"] = $data['back_url'];
        $param["member_category"] = 0;
        $param["member_role"] = 'R001';//测试环境默认收单商户R100，分账方为R003
        $param["phone"] = $data['mobile'];
        $param["name"] = $data['id_card_name'];
        $param["identity_type"] = 1;
        $param["identity_name"] = $data['id_card_name'];
        $param["identity_no"] = $this->rsaEncrypt($data['id_card_num']);

        //$param["bank_province_code"] = $data['province_code'];
        //$param["bank_city_code"] = $data['city_code'];
        //$param["bank_area_code"] = $data['area_code'];
        //$param["bank_code"] = $data['bank_code'];
        $param["bank_card_no"] = $this->rsaEncrypt($data['bank_num']);

        $param["merchant_name"] = $data['shop_name'];
        //$param["mcc_code"] = $data[''];
        //$param["merchant_province_code"] = $data[''];
        //$param["merchant_city_code"] = $data[''];
        //$param["merchant_area_code"] = $data[''];
        $param["manage_address"] = $data['address'];
        //$param["biz_content"] = $data[''];
        //$param["seller_scale"] = (100-$data['commission_rate'])/100;
        $param["seller_scale"] = 0.7;
        $param["condition"] = 'ge';
        $param["identity_no_start_date"] = $data['id_card_start_time'];
        $param["identity_no_valid_date"] = $data['id_card_end_time'];
        //$param["identity_front_img_no"] = $data[''];
        //$param["identity_back_img_no"] = $data[''];
        //$param["account_opening_license_img_no"] = $data[''];

        $param["fee_rate"] = [
            'union_scan_debit'=>'0.50',
            'union_scan_debit_pct'=>'20',
            'union_scan_credit'=>'0.60',
            'wechat'=>'0.38',
            'alipay'=>'0.38',
        ];
        if ($param['open_part']==2){
            $param['esign_info']=[
                "A7"=>"0.5",
                "A8"=>"20",
                "A10"=>"0.6",
                "A19"=>"0.3",
                "A21"=>"",
                "A22"=>"",
                "A24"=>"",
                "A25"=>"",
                "A27"=>"",
                "A28"=>"",
                "A30"=>"",
                "A31"=>"",
                "A32"=>"",
                "A33"=>"",
                "A35"=>"",
                "A37"=>"",
                "A39"=>"",
                "A41"=>"",
                "A42"=>"",
                "A44"=>"",
                "A58"=>"",
                "A59"=>"√",
                "B12"=>"https://ww.wawalaigou.com",//网站地址
                "B14"=>"河南自贸试验区郑州片区(郑东)商务外环14号路劲大厦1115室",//办公地址
                "B15"=>"91410100MADN1F390J",//营业执照注册号
                "B16"=>"117.78.8.105",//交易IP地址
                "C1"=>"抖行(河南)数字科技有限公司",//特约商户信息授权函：授权公司名称
                "C2"=>"特约商户入驻合作协议",
                "C3"=>"提供对应服务",
                "E1"=>"抖行(河南)数字科技有限公司",
                "E2"=>$param["merchant_name"]."入驻合作协议",
                "E3"=>"3",
                "E4"=>"抖行(河南)数字科技有限公司",
                "E10"=>$param["merchant_name"],//结算授权委托书：合作公司名称
                "E11"=>70,
                //"E11"=>100-$data['commission_rate'],//结算授权委托书：商户分得最低分账比例
                "E13"=>"√",
                "E14"=>$param["merchant_name"],//结算授权委托书：合作公司名称
                "E15"=>"30"
            ];
        }
        //$param["fee_rate"] = $data[''];
        //$param["esign_info"] = $data[''];
        if ($data['subject_type']==3){
            //企业
            //$param["business_license_start_date"] = $data[''];
            //$param["business_license_valid_date"] = $data[''];
            //$param["business_license_img_no"] = $data[''];
            $param["member_type"] = 3;
            $param["business_license"] = $data['business_license_num'];
            //$param["merchant_nature"] = $data[''];//商户性质
        } elseif ($data['subject_type']==2){
            //个人 小微
            $param["member_type"] = 2;
        } else {
            //个体工商户
            $param["member_type"] = 4;

        }


        $this->bizContent = json_encode($param,320);

        $this->apiMethodName = 'member.open.part.page.url.get';
        $result = $this->execute();

        return $result;
    }

    //普通会员开户
    public function newCreateMember($data)
    {

        $param["out_member_no"] = $data['out_member_no'];
        //$param["out_member_no"] = '2_01234567';
        $param["out_merchant_no"] =  $data['out_merchant_no'];
        //$param["out_merchant_no"] = $data['shop_id'].'_'.\fast\Random::numeric(8);
        $param["open_part"] = 1;//1：普通会员 2：收单商户
        $param["back_url"] = $data['back_url'];
        $param["member_category"] = 0;
        $param["member_role"] = 'R001';//测试环境默认收单商户R100，分账方为R003
        $param["phone"] = $data['mobile'];
        $param["name"] = $data['id_card_name'];
        $param["identity_type"] = 1;
        $param["identity_name"] = $data['id_card_name'];
        $param["identity_no"] = $this->rsaEncrypt($data['id_card_num']);

        //$param["bank_province_code"] = $data['province_code'];
        //$param["bank_city_code"] = $data['city_code'];
        //$param["bank_area_code"] = $data['area_code'];
        //$param["bank_code"] = $data['bank_code'];
        $param["bank_card_no"] = $this->rsaEncrypt($data['bank_num']);

        $param["merchant_name"] = $data['shop_name'];
        //$param["mcc_code"] = $data[''];
        //$param["merchant_province_code"] = $data[''];
        //$param["merchant_city_code"] = $data[''];
        //$param["merchant_area_code"] = $data[''];
        $param["manage_address"] = $data['address'];
        //$param["biz_content"] = $data[''];
        //$param["seller_scale"] = (100-$data['commission_rate'])/100;
        $param["seller_scale"] = 0.7;
        $param["condition"] = 'ge';
        $param["identity_no_start_date"] = $data['id_card_start_time'];
        $param["identity_no_valid_date"] = $data['id_card_end_time'];
        //$param["identity_front_img_no"] = $data[''];
        //$param["identity_back_img_no"] = $data[''];
        //$param["account_opening_license_img_no"] = $data[''];

        $param["fee_rate"] = [
            'union_scan_debit'=>'0.50',
            'union_scan_debit_pct'=>'20',
            'union_scan_credit'=>'0.60',
            'wechat'=>'0.38',
            'alipay'=>'0.38',
        ];
        if ($param['open_part']==2){
            $param['esign_info']=[
                "A7"=>"0.5",
                "A8"=>"20",
                "A10"=>"0.6",
                "A19"=>"0.3",
                "A21"=>"",
                "A22"=>"",
                "A24"=>"",
                "A25"=>"",
                "A27"=>"",
                "A28"=>"",
                "A30"=>"",
                "A31"=>"",
                "A32"=>"",
                "A33"=>"",
                "A35"=>"",
                "A37"=>"",
                "A39"=>"",
                "A41"=>"",
                "A42"=>"",
                "A44"=>"",
                "A58"=>"",
                "A59"=>"√",
                "B12"=>"https://ww.wawalaigou.com",//网站地址
                "B14"=>"河南自贸试验区郑州片区(郑东)商务外环14号路劲大厦1115室",//办公地址
                "B15"=>"91410100MADN1F390J",//营业执照注册号
                "B16"=>"117.78.8.105",//交易IP地址
                "C1"=>"抖行(河南)数字科技有限公司",//特约商户信息授权函：授权公司名称
                "C2"=>"特约商户入驻合作协议",
                "C3"=>"提供对应服务",
                "E1"=>"抖行(河南)数字科技有限公司",
                "E2"=>$param["merchant_name"]."入驻合作协议",
                "E3"=>"3",
                "E4"=>"抖行(河南)数字科技有限公司",
                "E10"=>$param["merchant_name"],//结算授权委托书：合作公司名称
                "E11"=>70,
                //"E11"=>100-$data['commission_rate'],//结算授权委托书：商户分得最低分账比例
                "E13"=>"√",
                "E14"=>$param["merchant_name"],//结算授权委托书：合作公司名称
                "E15"=>"30"
            ];
        }
        //$param["fee_rate"] = $data[''];
        //$param["esign_info"] = $data[''];
        if ($data['subject_type']==3){
            //企业
            //$param["business_license_start_date"] = $data[''];
            //$param["business_license_valid_date"] = $data[''];
            //$param["business_license_img_no"] = $data[''];
            $param["member_type"] = 3;
            $param["business_license"] = $data['business_license_num'];
            //$param["merchant_nature"] = $data[''];//商户性质
        } elseif ($data['subject_type']==2){
            //个人 小微
            $param["member_type"] = 2;
        } else {
            //个体工商户
            $param["member_type"] = 4;

        }


        $this->bizContent = json_encode($param,320);

        $this->apiMethodName = 'member.open.part.page.url.get';
        $result = $this->execute();

        return $result;
    }


    // 上传图片
    public function upload($data)
    {
        $param["image_type"] = $data['image_type'];
        $param["image_name"] = $data['image_name'];
        $param["image_content"] = $data['image_content'];

        $this->bizContent = $param;
        $this->apiMethodName = 'file.upload';
        $result = $this->execute2();
        return $result;
    }

	
	// 个人开户
	public function createPersonMember($out_member_no)
	{
		$param["out_member_no"] = $out_member_no;
		$this->bizContent = json_encode($param);
		$this->apiMethodName = 'member.person.create';
		$result = $this->execute(); 
		return $result;
	}


    //会员开户结果通知
    public function memberOpen($data)
    {
        $param['member_no'] = $data['member_no'];
        $param["out_member_no"] = $data['out_member_no'];
        $param['mobile'] = $data['mobile'];
        $this->bizContent = json_encode($param);
        $this->apiMethodName = 'member.open';
        $result = $this->execute4();
        return $result;
    }

	public function getNotifyResult($request)
	{
		//获取签名
		$sign = $request['sign'];
		//组装签名原串
		$signStr = $request['app_id'].$request['timestamp'].$request['version'].$request['event_type'].$request['event'];
		//验签
		$seccess = $this->verify($signStr, $sign, self::$signType);
		if(!$seccess) {
			throw new Exception("返回值签名验证失败");
		}
		return $request;
	}
	
	public static function setAppId($appId) {
		return self::$appId = $appId;
	}
	
	public static function setServerUrl($gatewayUrl) {
		return self::$gatewayUrl = $gatewayUrl;
	}
	
	public static function getServerUrl() {
		return self::$gatewayUrl;
	}
	
	public static function setApiVersion($apiVersion) {
		return self::$apiVersion = $apiVersion;
	}
	
	public static function setDSAKey($DSAPublicKeyFilePath, $DSAPrivateKeyFilePath, $DSAPrivateKeyFilePassword) {
		self::$DSAPublicKeyFilePath = $DSAPublicKeyFilePath;
		self::$DSAPrivateKeyFilePath = $DSAPrivateKeyFilePath;
		self::$DSAPrivateKeyFilePassword = $DSAPrivateKeyFilePassword;
	}
	
	public static function setRSAKey($RSAPublicKeyFilePath, $RSAPrivateKeyFilePath, $RSAPrivateKeyFilePassword) {
		self::$RSAPublicKeyFilePath = $RSAPublicKeyFilePath;
		self::$RSAPrivateKeyFilePath = $RSAPrivateKeyFilePath;
		self::$RSAPrivateKeyFilePassword = $RSAPrivateKeyFilePassword;
	}

    public function execute4($authToken = null, $appInfoAuthtoken = null) {
        //  如果两者编码不一致，会出现签名验签或者乱码
        if (strcasecmp(self::$fileCharset, self::$postCharset)) {

            // writeLog("本地文件字符集编码与表单提交编码不一致，请务必设置成一样，属性名分别为postCharset!");
            throw new Exception("文件编码：[" . self::$fileCharset . "] 与表单提交编码：[" . self::$postCharset . "]两者不一致!");
        }
        $iv = self::$apiVersion;

        //组装系统参数
        $sysParams["app_id"] = self::$appId;
        $sysParams["version"] = $iv;
        $sysParams["service"] = $this->apiMethodName;
        $sysParams["timestamp"] = time();

        //获取业务参数
        $sysParams["params"] = $this->bizContent;
        //签名
        $sysParams["sign"] = $this->generateSign($sysParams, self::$signType);

        $result = $this->getNotifyResult($sysParams);
        $result = $this->checkResult($result);
        return $result;
    }

	public function execute($authToken = null, $appInfoAuthtoken = null) {
		//  如果两者编码不一致，会出现签名验签或者乱码
		if (strcasecmp(self::$fileCharset, self::$postCharset)) {

			// writeLog("本地文件字符集编码与表单提交编码不一致，请务必设置成一样，属性名分别为postCharset!");
			throw new Exception("文件编码：[" . self::$fileCharset . "] 与表单提交编码：[" . self::$postCharset . "]两者不一致!");
		}
		$iv = self::$apiVersion;

		//组装系统参数
		$sysParams["app_id"] = self::$appId;
		$sysParams["version"] = $iv;
		$sysParams["service"] = $this->apiMethodName;
		$sysParams["timestamp"] = time();

		//获取业务参数
		$sysParams["params"] = $this->bizContent;
		//签名
		$sysParams["sign"] = $this->generateSign($sysParams, self::$signType);


		$result = $this->request($sysParams);
		$result = $this->checkResult($result);
		return $result;
	}

	public function execute2($authToken = null, $appInfoAuthtoken = null) {
		//  如果两者编码不一致，会出现签名验签或者乱码
		if (strcasecmp(self::$fileCharset, self::$postCharset)) {

			// writeLog("本地文件字符集编码与表单提交编码不一致，请务必设置成一样，属性名分别为postCharset!");
			throw new Exception("文件编码：[" . self::$fileCharset . "] 与表单提交编码：[" . self::$postCharset . "]两者不一致!");
		}
		$iv = self::$apiVersion;

		//组装系统参数
		$sysParams["app_id"] = self::$appId;
		$sysParams["version"] = $iv;
		$sysParams["service"] = $this->apiMethodName;
		$sysParams["timestamp"] = time();

		//获取业务参数
		foreach ($this->bizContent as $key=>$value) {
			$sysParams[$key] = $value;
		}
		//签名
		$sysParams["sign"] = $this->generateSign($sysParams, self::$signType);

		$result = $this->request2($sysParams);
		$result = $this->checkResult($result);
		return $result;
	}

	public function execute3($authToken = null, $appInfoAuthtoken = null) {
		//  如果两者编码不一致，会出现签名验签或者乱码
		if (strcasecmp(self::$fileCharset, self::$postCharset)) {

			// writeLog("本地文件字符集编码与表单提交编码不一致，请务必设置成一样，属性名分别为postCharset!");
			throw new Exception("文件编码：[" . self::$fileCharset . "] 与表单提交编码：[" . self::$postCharset . "]两者不一致!");
		}
		$iv = self::$apiVersion;

		//组装系统参数
		$sysParams["app_id"] = self::$appId;
		$sysParams["version"] = $iv;
		$sysParams["service"] = $this->apiMethodName;
		$sysParams["timestamp"] = time();

		//获取业务参数
		$sysParams["params"] = $this->bizContent;
		//签名
		$sysParams["sign"] = $this->generateSign($sysParams, self::$signType);

		return $sysParams;
	}
	
	private function request($args){
		global $log;
		$ch = curl_init () ;
		curl_setopt($ch, CURLOPT_URL, self::$gatewayUrl);
		$sb = '';
		$reqbody = array();
		foreach($args as $entry_key => $entry_value){
			$sb .= $entry_key.'='.urlencode($entry_value).'&';
		}
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $sb);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_AUTOREFERER, 0);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-length', count($reqbody)));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		$result = curl_exec($ch);
		curl_close($ch);
		return $result;
	}
	
	private function request2($args){
		global $log;
		$ch = curl_init () ;
		curl_setopt($ch, CURLOPT_URL, self::$gatewayUrl);
		$sb2 = array();
		$reqbody = array();
		foreach($args as $entry_key => $entry_value){
			$sb2[$entry_key] = $entry_value;
		}
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $sb2);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_AUTOREFERER, 0);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-length', count($reqbody)));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		$result = curl_exec($ch);
		curl_close($ch);
		return $result;
	}
	
	/**
	 * 检查服务调用结果是否正确，如果服务调用失败，则抛出失败异常
	 * @param result 服务调用的返回结果对象
	 * @throws Exception
	 */
	private function checkResult($result){
		global $log;
		$arr = json_decode($result, true);

		if (is_string($arr['response'])) {
			$response = json_decode($arr['response'], true);
		} else {
			$response = $arr['response'];
		}
		$sign = $arr['sign'];
		if($sign != null){
 			$seccess = $this->verify($arr['response'], $sign, self::$signType);
			if(!$seccess)
				throw new Exception("返回值签名验证失败");
		}
		return $response;
	}

	/**
	 * 校验$value是否非空
	 *  if not set ,return true;
	 *    if is null , return true;
	 **/
	protected function checkEmpty($value) {
		if (!isset($value))
			return true;
		if ($value === null)
			return true;
		if (trim($value) === "")
			return true;

		return false;
	}

	//验签
	function verify($data, $sign, $signType = 'RSA') {
		//读取公钥文件
		$pubKey = file_get_contents(self::$DSAPublicKeyFilePath);
		//转换为openssl格式密钥
		$res = openssl_get_publickey($pubKey);

		($res) or die('公钥错误。请检查公钥文件格式是否正确');  

		//调用openssl内置方法验签，返回bool值
		if (!is_string($data)) {
			$data = json_encode($data);
		}
		if ("RSA2" == $signType) {
			$result = openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256);
		} else if ("DSA" == $signType) {
			$result = openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_DSS1);
		} else {
			$result = openssl_verify($data, base64_decode($sign), $res);
		}
		if ($result == 1) {
			$result = true;
		} else {
			$result = false;
		}
		if(!$this->checkEmpty(self::$DSAPublicKeyFilePath)){
			openssl_free_key($res);
		}
		return $result;
	}

	public function generateSign($params, $signType = "DSA") {
		return $this->sign($this->getSignContent($params), $signType);
	}

	protected function getSignContent($params) {

		$stringToBeSigned = '';
		if(array_key_exists("app_id", $params)) {
			$stringToBeSigned .= $params['app_id'];
		}
		if(array_key_exists("timestamp", $params)) {
			$stringToBeSigned .= $params['timestamp'];
		}
		if(array_key_exists("version", $params)) {
			$stringToBeSigned .= $params['version'];
		}
		if(array_key_exists("service", $params)) {
			$stringToBeSigned .= $params['service'];
		}
		if(array_key_exists("params", $params)) {
			$stringToBeSigned .= $params['params'];
		}
		if(array_key_exists("image_type", $params)) {
			$stringToBeSigned .= $params['image_type'];
		}
		if(array_key_exists("image_name", $params)) {
			$stringToBeSigned .= $params['image_name'];
		}
		//$stringToBeSigned = $params['app_id'] . $params['timestamp'] . $params['version'] . $params['service'] . $params['params'];
		$stringToBeSigned = str_replace("\r\n", "", $stringToBeSigned);
		return $stringToBeSigned;
	}

	protected function sign($data, $signType = "DSA") {
		if ("DSA" == $signType) {
			$file = file_get_contents(self::$DSAPrivateKeyFilePath);
			openssl_pkcs12_read($file, $res, self::$DSAPrivateKeyFilePassword);
		} else {
			$priKey = file_get_contents(self::$RSAPrivateKeyFilePath);
			$res = openssl_get_privatekey($priKey, self::$RSAPrivateKeyFilePassword);
		}

		($res) or die('您使用的私钥格式错误，请检查私钥配置');
		if ("RSA2" == $signType) {
			openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
		} else if ("DSA" == $signType) {
			openssl_sign($data, $sign, $res['pkey'], OPENSSL_ALGO_DSS1);
		} else {
			openssl_sign($data, $sign, $res);
		}
		if("DSA" != $signType && !$this->checkEmpty(self::$DSAPrivateKeyFilePath)){
			openssl_free_key($res);
		}
		$sign = base64_encode($sign);
		return $sign;
	}

	public function rsaEncrypt($data) {
		//读取公钥文件
		$pubKey = file_get_contents(self::$RSAPublicKeyFilePath);
		//转换为openssl格式密钥
		$res = openssl_get_publickey($pubKey);
		if (!openssl_public_encrypt($data, $chrtext, $res, OPENSSL_PKCS1_PADDING)) {
			echo "<br/>" . openssl_error_string() . "<br/>";
		}
		return base64_encode($chrtext);
	}

	public function rsaDecrypt($data) {
		//读取私钥文件
		$priKey = file_get_contents(self::$RSAPrivateKeyFilePath);
		//转换为openssl格式密钥
		openssl_pkcs12_read($priKey, $res, self::$RSAPrivateKeyFilePassword);
		$res1 = openssl_pkey_get_private($res['pkey']);
		if (!openssl_private_decrypt(base64_decode($data), $dcyCont, $res1, OPENSSL_PKCS1_PADDING)) {
			echo "<br/>---" . openssl_error_string() . "<br/>";
		}
		return $dcyCont;
	}
}